/*
Time :2021-04-14 15:11:22
author :selfeasy
email :selfeasy@qq.com
desc: 实现集合的功能，支持切片的交集、并集、差集、补集
*/

package set

// 交集
func InterSet(source, target []interface{}) (inter []interface{}) {
	all := make(map[interface{}]uint8)
	for _, value := range source { // 01
		all[value] = all[value] | 1<<0
	}
	for _, value := range target { // 10
		all[value] = all[value] | 1<<1
	}
	for k, v := range all {
		a := v&(1<<0) != 0
		b := v&(1<<1) != 0
		if a && b {
			inter = append(inter, k)
		}
	}
	return
}

// 并集
func UnionSet(source, target []interface{}) (union []interface{}) {
	all := make(map[interface{}]uint8)
	for _, value := range source { // 01
		all[value] = all[value] | 1<<0
	}
	// fmt.Println(all)
	for _, value := range target { // 10
		all[value] = all[value] | 1<<1
	}
	// fmt.Println(all)
	for k, v := range all {
		a := v&(1<<0) != 0
		b := v&(1<<1) != 0
		if a || b {
			union = append(union, k)
		}
	}
	return
}

// 差集
func DiffSet(source, target []interface{}) (diff []interface{}) {
	all := make(map[interface{}]uint8)
	for _, value := range source { // 01
		all[value] = all[value] | 1<<0
	}
	// fmt.Println(all)
	for _, value := range target { // 10
		all[value] = all[value] | 1<<1
	}
	// fmt.Println(all)
	for k, v := range all {
		a := v&(1<<0) != 0
		b := v&(1<<1) != 0
		if a && !b {
			diff = append(diff, k)
		}
	}
	return
}

// 补集 非共同元素
func SuppleSet(source, target []interface{}) (sup []interface{}) {
	sup = DiffSet(UnionSet(source, target), InterSet(source, target))
	return
}

// 元素是否在切片中
func ItemInSlice(item interface{}, target []interface{}) (flag bool) {
	flag = false
	for _, value := range target {
		if item == value {
			flag = true
			break
		}
	}
	return
}
